跳到主要内容

实时 MQTT 控制

提示

实时MQTT控制用于实时控制。要提前发送调度,请参阅调度MQTT控制

本指南将帮助您在您的SmartgridOne Controller上配置MQTT,以远程控制和监测电池和太阳能电池板的安装。

您需要的

  1. 具备互联网连接的SmartgridOne Controller
  2. MQTT凭据:可以通过发送电子邮件至support@eniris.be请求。
  3. Python开发环境(或任何其他MQTT客户端)。本指南使用一个简单的Python示例来帮助您入门MQTT和发送命令。我们推荐使用Python,因为易于使用,但也支持其他MQTT客户端。

附加信息

MQTT是一种快速的互联网通信协议。它是一个发布/订阅消息系统,允许您的机器与SmartgridOne Controller之间建立直接连接。您的资产被分类为太阳能、电池、电动汽车和HVAC组。

第一次配置(新用户的起点)

我有一个SmartgridOne Controller,我希望设置为MQTT远程控制。

1. 检查您的网络

确保您的网络允许通过端口1883传输mqtt网络流量。您可以使用以下命令完成此操作:

nc -zv mqtt.eniris.be 1883

如果该命令不可用,您还可以下载并执行此python代码

如果不确定,请咨询您的网络工程师,或者在发生连接错误时暂时使用手机的4G/5G热点。

备注

当端口1883在您的网络上不可访问时,我们在端口80提供了备份。可以在本手册的后续步骤中在您的MQTT客户端中进行配置。

2. 添加您的设备

登录到调试界面,确保设备已添加SmartgridOne Controller

3. 添加MQTT外部信号

Image 1
Image 1
Image 1
Image 1

4. 启用MQTT远程信号

字段'VPP ID'必须留空。

备用机制超时指示SmartgridOne Controller应等待多长时间以获取新命令。当SmartgridOne Controller停止接收命令时,它将在超时后自动切换为默认策略。

然后,选择您希望包含在MQTT远程控制中的所有设备。

Image 1
Image 1

5. 远程信号已添加

现在已在SmartgridOne Controller上激活MQTT远程控制界面。

现在我们准备使用一个简单示例发送一些基本命令。状态列告诉您任何命令是否处于活动状态。

Image 1

Python演示脚本

一个好的起点是使用一个简单的示例测试您新设置的集成。

此测试代码持续发送以下命令:

  • 电池:以5 kW充电
  • 太阳能:电力设置为0 kW

SmartgridOne Controller持续响应一个包含观察到的电网和资产功率值的“反馈”消息。此功能也包含在此示例中。

请在您首选的Python IDE中下载以下文件。填写您的序列号和MQTT凭据,然后执行脚本:

如果以上成功,您可以继续发送其他类型的命令。所有命令在我们的MQTT远程控制文档中都有描述。

用于发送命令的MQTT文档

本节详细介绍了远程控制SmartgridOne Controller网络内设备的电源策略所需的MQTT消息格式和有效负载要求。

MQTT主题

用于发送命令的MQTT主题结构如下:

standard1/rp_one_s/remoteControlMetrics/'controller SN'

其中'controller SN'应替换为您打算控制的SmartgridOne Controller的实际序列号。

MQTT有效负载结构

命令以JSON有效负载的形式发送。有效负载结构旨在指定智能电网系统不同组件的各种电源管理策略和设定点。以下是有效负载的大纲及详细字段描述:

{
"extraTags": {
"nodeId": "<Controller SN>_site_0"
},
"time": "<Unix Timestamp>",
"fields": {
"<Component Policy>": "<Policy Type>",
"<Component Power Setpoint>": <Setpoint in watts>
}
}

字段描述

提示

可以同时控制多种设备类型(例如,电池 + 太阳能)。

  • extraTags(对象):
    • nodeId(字符串):在SmartgridOne Controller网络内的唯一标识符。对于大多数SmartgridOne Controller设备,这等于您的序列号,后跟'_site_0'。
  • time(整数):以秒为单位的Unix时间戳,指示消息发送的时间。
  • fields(对象):
    • <Component>_policy(字符串):组件的策略类型。它是可选的,如果未指定,系统将退回到SmartgridOne Controller的默认设置。
    • <Component>_power_setpoint_w(浮点):组件的预期功率设定点,以瓦特为单位。此项为可选,仅在指定了相应策略时相关。

组件和政策

信息

相同类型的资产(例如,两个电池)将作为一个组件组合。比如,当安装两个5 kWh电池时,将被视为一个10 kWh电池。

fields对象中的每个组件可以包括一个政策和一个功率设定点。可以控制以下组件:

  • solar_policysolar_power_setpoint_w

    • 控制太阳能发电政策和设定点。支持的政策:
      • 政策设定点:设置所有连接的太阳能安装组合产生的最大功率。字段solar_power_setpoint_w应设置为以瓦特为单位的生产功率限制。
      • 政策馈入限制:以满功率生产,遵循当前的电网限制。
      • 政策成本:启用日先价格(EPEX现货市场)成本最小化太阳能生产。当出现负注入价格时,我们限制生产以满足自身消费。当提取和注入价格均为负时,我们关闭所有太阳能安装。字段solar_power_setpoint_w被忽略。
      • 政策关闭:禁用所有太阳能资产的所有交互。警告:在此模式下不提供限制保护。字段solar_power_setpoint_w被忽略。
  • storage_policystorage_power_setpoint_w

  • 控制能量存储系统的策略和功率放电或充电速率。

    • 策略设定点:为电池组设置总充电功率(正设定点)或放电功率(负设定点)。当多个电池连接时,设定点通过可用的充电/放电功率进行分配,以平等地施加负荷到电池上。字段 storage_power_setpoint_w 设置为所需的电池功率。
    • 策略成本:通过在便宜的时段充电并在昂贵的时段使用能量,启用电池的日提前价格(EPEX现货市场)成本优化。字段 storage_power_setpoint_w 被忽略。
    • 策略自消耗:启用电池上的简单自消耗算法。在太阳能过剩生产时,能量存储到电池中,当太阳落下时,从电池中提取能量。字段 storage_power_setpoint_w 被忽略。
    • 策略关闭:禁用所有电池资产的交互。警告:在此模式下,限制没有受到保护。字段 storage_power_setpoint_w 被忽略。
  • heat_pump_policy

    • 切换热泵系统的开/关。最低和最高开启时间将始终得到遵守。
      • 策略成本:启用热泵的日提前价格(EPEX现货市场)成本优化。当地动态定价算法决定最佳的开启时间段。
      • 策略自消耗:如果产生了过剩的太阳能,则开启热泵。
      • 策略关机:关闭热泵。
      • 策略开机:开启热泵。
  • switched_load_policy

    • 切换继电器控制的系统的开/关。这可以是内置继电器或网络连接的继电器。
      • 策略成本:启用继电器的日提前价格(EPEX现货市场)成本优化。
      • 策略自消耗:如果产生了过剩的太阳能,则开启继电器。
      • 策略关机
      • 策略开机
  • variable_power_load_policyvariable_power_load_power_setpoint_w

    • 管理电动车的电力消耗政策和设定点。
      • 策略设定点:为电动车组设置总充电功率。字段 variable_power_load_power_setpoint_w 设置为所需的充电功率。
      • 策略成本:通过在便宜的时段充电来启用电池的日提前价格(EPEX现货市场)成本优化。字段 variable_power_load_power_setpoint_w 被忽略。
      • 策略自消耗:如果产生了过剩的太阳能,则启用充电。字段 variable_power_load_power_setpoint_w 被忽略。
      • 策略关闭:禁用所有电动车资产的交互。字段 variable_power_load_power_setpoint_w 被忽略。
  • site_policysite_power_setpoint_w

    • 管理站点出口限制。
      • 策略出口:为站点设置出口限制。字段 site_power_setpoint_w 设置为出口限制。
      • 策略默认:将站点限制恢复为控制器配置中设置的默认出口功率。

设备控制

特定设备也可以被控制,而不是基于类型的设备组。消息的结构相同:

  • nodeId_policynodeId_power_setpoint_w
信息

当两个命令发送到同一资产时(例如,一个设备特定的命令给太阳能逆变器,以及发送给所有太阳能设备的命令)时,设备特定控制方法将优先于设备类型控制。

回退行为

对于每个组件,如果未指定 _policy 和 _power_setpoint_w,系统将自动使用在 SmartgridOne Controller 中配置的回退策略。这确保每个设备或设备组安全地运行,即使未提供特定指令,仍然继续运行。

如果没有命令被发送,经过60秒(或配置的超时期限),资产的默认策略将重新激活。

取消现有命令并回退到本地控制模式

可以通过发送 回退命令 消息来取消活动命令。

回退命令

回退命令将立即取消现有命令,而 SmartgridOne Controller 将接管安装的控制。执行的策略取决于在 SmartgridOne Controller 设置中所设定的内容。

这也可以用于当次级控制信号(如计划)用作回退的情况。

消息示例:

{
"extraTags": {
"nodeId": "<Controller SN>_site_0"
},
"time": "<Unix Timestamp>",
"fields": {
"<Component Policy>": "fallback",
}
}

空命令

可以随时发送空命令以收集站点信息。这不会取消当前命令,也不会覆盖来自优先级较低的次级控制信号的命令。

空命令的结构如下:

{
"extraTags": {
"nodeId": "<Controller SN>_site_0"
},
"time": "<Unix Timestamp>",
"fields": {}
}

示例有效负载

下面是设置各种策略和设定点的有效负载示例:

{
"extraTags": {
"nodeId": "OM12404080000000000_site_0"
},
"time": 1714652046,
"fields": {
"solar_policy": "setpoint",
"solar_power_setpoint_w": 5000,
"storage_policy": "setpoint",
"storage_power_setpoint_w": -5000
}
}

在此示例中,太阳能功率设置为生成高达5000瓦,能量存储系统被设置为以5000瓦的速率充电或放电,具体取决于设定点值的符号。如果省略了 solar_policy 或 storage_policy,则相应的设备将恢复为由 SmartgridOne Controller 确定的默认设置。

MQTT 收反馈文档

本节概述了通过 MQTT 发送的 SmartgridOne Controller 的反馈消息的结构和内容。这些消息在命令被处理后发布到主题 standard1/outbound/remoteControlMetrics/feedback/<Controller SN>

MQTT 反馈主题

反馈 MQTT 主题的结构如下:

standard1/outbound/remoteControlMetrics/feedback/<Controller SN>

其中 <Controller SN> 应替换为发送反馈的 SmartgridOne Controller 的序列号。

MQTT 反馈有效负载结构

备注

所有资产根据其类型进行分组。这意味着两个3 kW的单独太阳能安装将被视为一个6 kW的资产。

反馈消息的格式为 JSON 有效负载。这些有效负载提供了在应用设定点命令后,考虑电网/设备限制的系统状态的详细反馈。下面是反馈有效负载的结构及其字段的描述:

{
"time": "<Unix Timestamp>",
"data": {
"state": {
"grid": {
"active_power_W": <电网实际功率(瓦特)>,
"today_imported_energy_Wh": <电网进口能量(瓦特小时)>,
"today_exported_energy_Wh": <电网出口能量(瓦特小时)>,
"import_limit_W": <电网进口限制(瓦特)>,
"export_limit_W": <电网出口限制(瓦特)>,
},
"vpp_id": "<虚拟电厂标识符>",
"storage": {
{
"energy_stored_Wh": <储存的能量(瓦时)>,
"energy_capacity_Wh": <总能量容量(瓦时)>,
"mean_soc_perc": <平均充电状态百分比>,
"active_power_W": <有功功率(瓦)>,
"executed_power_W": <发送到设备的功率设定值(瓦)>,
"executed_policy": <控制器执行的策略>,
"max_charge_power_W": <最大充电功率(瓦)>,
"max_discharge_power_W": <最大放电功率(瓦)>,
"today_charged_Wh": <今天充电的能量(瓦时)>,
"today_discharged_Wh": <今天放电的能量(瓦时)>,
"nr_devices": <已安装的受控储能设备数量>
},
"solar": {
"active_power_W": <太阳能有功功率(瓦)>,
"executed_power_W": <发送到设备的功率设定值(瓦)>,
"executed_policy": <控制器执行的策略>,
"capacity_W": <太阳能容量(瓦)>,
"today_energy_Wh": <今天产生的能量(瓦时)>,
"nr_devices": <已安装的受控太阳能设备数量>
},
"heat_pump": {
"executed_policy": <控制器执行的策略>,
"operation_modes": <热泵运行模式>,
"executed_power_W": <发送到设备的功率设定值(瓦)>,
"nr_devices": <已安装的受控热泵设备数量>
},
"switched_load": {
"executed_policy": <控制器执行的策略>,
"devices_on": <开启的设备数量>,
"devices_off": <关闭的设备数量>,
"executed_power_W": <发送到设备的功率设定值(瓦)>,
"nr_devices": <已安装的受控切换负载设备数量>
},
"variable_load": {
"executed_policy": <控制器执行的策略>,
"executed_power_W": <发送到设备的功率设定值(瓦)>,
"active_power_W": <设备功率(瓦)>,
"ev_requiring_charge": <电动汽车是否需要充电>,
"currentL1_A": <相位1的设备电流(安培)>,
"currentL2_A": <相位2的设备电流(安培)>,
"currentL3_A": <相位3的设备电流(安培)>,
"executed_current_A": <发送到设备的电流设定值(安培)>,
"today_charged_Wh": <今天充电的能量(瓦时)>,
"today_discharged_Wh": <今天放电的能量(瓦时)>,
"total_charged_Wh": <总充电能量(瓦时)>,
"total_discharged_Wh": <总放电能量(瓦时)>,
"min_charge_current_A": <最小充电电流(安培)>,
"max_charge_current_A": <最大充电电流(安培)>,
"allow_zero_current": <充电器是否支持暂停>,
}
},
"response_code": <响应代码>
},
"fields": {},
"requestTime": "<Unix时间戳>",
"time": "<Unix时间戳>",
"siteNodeId": "<控制器 SN>_site_0"
}
- executed_policy (Str): 已应用于可控设备的政策,
- executed_power_W (Float): 从资产请求的总功率的总和,由我们的控制算法发送。
- active_power_W (Float): 表示电网当前的有功功率,以瓦特为单位。
- ev_requiring_charge (Bool): 该电动车是否需要充电。(汽车是否已连接)。
- currentL1_A (Float): 阶段1上设备的电流,以安培为单位。
- currentL2_A (Float): 阶段2上设备的电流,以安培为单位。
- currentL3_A (Float): 阶段3上设备的电流,以安培为单位。
- executed_current_A (Float): 从资产请求的总电流的总和,由我们的控制算法发送。
- today_charged_Wh (Float): 今天充入电动车充电器资产的能量。注意:今天的时间以UTC为准。
- today_discharged_Wh (Float): 今天充入电动车充电器资产的能量。注意:今天的时间以UTC为准。
- total_charged_Wh (Float): 充入电动车充电器资产的总能量。
- total_discharged_Wh (Float): 充入电动车充电器资产的总能量。
- min_charge_current_A (Float): 电动车可以充电的最小电流。
- max_charge_current_A (Float): 电动车可以充电的最大电流。
- allow_zero_current (Bool): 电动车充电器是否允许暂停。
- nodeId (Object):
- 如果命令中包含nodeId,反馈将包含设备的相应状态。
- response_code (Int):
- 指示操作的状态。响应代码0通常表示成功,而其他值则可能指示不同类型的错误或状态信息(这些应在单独的参考中详细说明)。

### 示例反馈有效载荷
以下是一个反馈消息的示例,该消息跟随设置各种功率设定点的命令:

<ClickableImage src="/img/generic/mqtt-example-feedback.png" alt="Image 1" maxWidth="450px" />

该反馈展示了在执行设定点后系统的当前操作状态,指示了对太阳能发电、储存和整体电网交互的影响。

## 支持的MQTT版本和对未经授权主题的行为
使用MQTT时,重要的是要考虑版本3.13.1.15.0之间规范的差异,特别是在客户端发布到未经授权主题时代理的行为。

根据MQTT 3.1.1规范(详见OASIS MQTT 3.1.1规范,节MQTT-3.3.5-2),一旦客户端向其没有权限的主题发送PUBLISH,代理必须立即终止连接。这种行为可能会导致尝试发布到配置错误或未经授权主题的客户端意外断开连接。

在MQTT 3.1中,这项要求并不存在。当客户端在此版本中发布到未经授权的主题时,代理通常会忽略该消息(静默丢弃),而不会终止连接。这使得在某些情况下,MQTT 3.1更适合在对配置错误或暂时缺失的权限的鲁棒性比严格的安全性执行更重要时使用。

尽管MQTT 5.0引入了处理原因代码的能力(例如带有拒绝原因的PUBACK),但这需要客户端和服务器端的支持。因此,迁移到MQTT 5.0要求额外的实施工作。

__忽视兼容性的后果:__
如果客户端使用MQTT 3.1.1连接并尝试向未经授权的主题发布消息,代理将会突然终止会话。这可能导致不稳定、失去连接或由于重复重连尝试而增加负载。

__推荐的方法:__
对于可能(暂时)尝试向未经授权主题发布消息的客户端,或未严格实施错误处理的系统,我们建议使用MQTT 3.1。这将确保更稳定的连接,并避免在运行时发生意外断开。